package com.bdqn.crm.config;
import com.bdqn.crm.config.shiro.MyShiroRealm;
import com.bdqn.crm.pojo.Right;
import com.bdqn.crm.pojo.User;
import com.bdqn.crm.service.RoleService;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Resource
    private RoleService roleService;
    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    public RedisManager redisManager(){
        RedisManager redisManager = new RedisManager();
        redisManager.setHost(host);
        redisManager.setPassword(password);
        redisManager.setTimeout(timeout);
        redisManager.setPort(port);
        return redisManager;
    }

    public RedisCacheManager redisCacheManager(){
        RedisCacheManager redisCacheManager = new org.crazycake.shiro.RedisCacheManager();
        redisCacheManager.setPrincipalIdFieldName("userName");
        redisCacheManager.setExpire(1800);
        return redisCacheManager;
    }

    //会话操作
    @Bean
    public RedisSessionDAO redisSessionDAO(){
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        return redisSessionDAO;
    }

    //会话管理
    @Bean
    public DefaultWebSessionManager sessionManager(){
      DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO());
        return sessionManager;
    }

    @Bean
    public MyShiroRealm myShiroRealm() {    // 自定义 Realm
        MyShiroRealm shiroRealm = new MyShiroRealm();
        shiroRealm.setCachingEnabled(true);
        shiroRealm.setAuthenticationCachingEnabled(true);
        shiroRealm.setAuthenticationCacheName("aithorizationCache");
        return shiroRealm;
    }

    @Bean
    public SecurityManager securityManager() {       // 安全管理器 SecurityManager
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        // 注入 Realm
        securityManager.setRealm(myShiroRealm());
        //注入缓存管理
        securityManager.setCacheManager(redisCacheManager());
        //注入会话管理
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactory(SecurityManager securityManager) {    // Shiro 过滤器
        ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
        //注入SecurityManager
        shiroFilterFactory.setSecurityManager(securityManager);
        //权限认证:使用Filter控制资源(URL)的访问
        shiroFilterFactory.setLoginUrl("/index");
        shiroFilterFactory.setSuccessUrl("/main");
        shiroFilterFactory.setUnauthorizedUrl("/403");
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();//必须使用LinkedHashMap，保证有序
        //配置可以匿名访问的资源
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/images/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/localjs/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        List<Right> rights = roleService.finAllRights();
        for (Right right : rights) {
            if (right.getRightUrl()!= null &&!right.getRightUrl().trim().equals("")) {
                filterChainDefinitionMap.put(right.getRightUrl(), "perms[" + right.getRightCode() + "]");
            }
        }
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactory.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactory;
    }


    /*@Bean
       public ShiroFilterFactoryBean shiroFilterFactory(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
            shiroFilterFactory.setSecurityManager(securityManager);
            shiroFilterFactory.setLoginUrl("/index");
            shiroFilterFactory.setSuccessUrl("/main");
            shiroFilterFactory.setUnauthorizedUrl("/403");
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
            filterChainDefinitionMap.put("/css/**", "anon");
            filterChainDefinitionMap.put("/fonts/**", "anon");
            filterChainDefinitionMap.put("/images/**", "anon");
            filterChainDefinitionMap.put("/js/**", "anon");
            filterChainDefinitionMap.put("/localjs/**", "anon");
            filterChainDefinitionMap.put("/login", "anon");
            filterChainDefinitionMap.put("/logout", "logout");
            List<Right> rights = roleService.finAllRights();
            for (Right right : rights) {
                if (right.getRightUrl()!= null &&!right.getRightUrl().trim().equals("")) {
                    filterChainDefinitionMap.put(right.getRightUrl(), "perms[" + right.getRightCode() + "]");
                }
            }
            filterChainDefinitionMap.put("/**", "authc");
            shiroFilterFactory.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactory;
        }*/

    //确保MyShiroRealm 类正确实现 AuthorizingRealm 接口，并在其中重写此方法
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("调试 myShiroRealm.doGetAuthorizationInfo() 获取权限信息");
        User sysUser = (User) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(sysUser.getRole().getRoleName());
        info.addStringPermission("用户列表");
        if ("管理员".equals(sysUser.getRole().getRoleName())) {
            info.addStringPermission("添加用户");
            info.addStringPermission("修改用户");
            info.addStringPermission("删除用户");
        }
        return info;
    }
}
